<cfcomponent name="_coop" output="false">
	<cfparam name="REQUEST._remote" default="false">
	<cfscript>
	if(REQUEST._remote){
		onRemoteStart();
	}
	</cfscript>
	<cffunction name="init" access="public" output="false">
		<cfargument name="configuration" required="true">
		<cfargument name="sosContentObj" required="true">
		<cfargument name="api" default="#structNew()#">
		<cfargument name="attributes" default="#structNew()#">
		<cfscript>
		var coProcessorObj = '';
		
		VARIABLES._api = ARGUMENTS.api;
		VARIABLES.attributes = ARGUMENTS.attributes;
		
		// Set up the configuration variables that the tags will need
		VARIABLES.config = structNew();
		VARIABLES.config.classPath = arguments.configuration.server.shareClasspath;
		VARIABLES.config.path = arguments.configuration.server.sharePath;
		VARIABLES.config.webService = "/" & replace(arguments.configuration.current.root.coProcessorClassPath,".","/","all") & ".cfc";
		this.sosContent = arguments.sosContentObj;
		
		//Create the coProcessor object
		/*
		try {
			coProcessorObj = createObject("component","#arguments.configuration.current.root.coProcessorClassPath#");
			return coProcessorObj;
		} catch (any err) {
			return this;
			// coProcessorObj = createObject("component","share.objects.coop.coop");
		}
		// Mixin the coProcessor
		structAppend(this,coProcessorObj);
		structAppend(variables,coProcessorObj);
		*/
		return this;
		</cfscript>
	</cffunction>
	
	<cffunction name="createAttributeList" output="false" access="public" returntype="String">
		<cfargument name="attributes">
		<cfargument name="standardattributes">
		<cfargument name="rootStruct">
		<cfscript>
		var attributeStruct = arguments.attributes;
		var _attributes = arguments.attributes;
		var attributeList = '';
		var iStructKey = '';
		var root = arguments.rootStruct;
		for (iStructKey in _attributes) {
			if (NOT listFindNoCase(arguments.standardAttributes,iStructKey) AND isSimpleValue(_attributes[iStructKey]) AND left(iStructKey,1) NEQ "_") {
				attributeList = attributeList & ' ' & iStructKey & '="#_attributes[iStructKey]#"';
			}
		}
		return attributeList;
		</cfscript>
	</cffunction>
	
	<cffunction name="createPageState" output="false" access="public">
		
	</cffunction>
	
	<cffunction name="get_webService" output="false" access="public">
		<cfscript>
		return VARIABLES.config.webService & "?wsdl";
		</cfscript>
	</cffunction>
	
	<cffunction name="get_ajaxService" output="false" access="public">
		<cfargument name="method" default="">
		<cfscript>
		if(len(arguments.method)){
			return VARIABLES.config.webService & "?method=#ARGUMENTS.method#";
		} else {
			return VARIABLES.config.webService;
		}
		</cfscript>
	</cffunction>

	<cffunction name="fieldParam" output="false">
		<cfargument name="initAttribs">
		<cfargument name="tagName">
		<cfargument name="value">
		<cfscript>
			returnValue = arguments.value;
			if (structKeyExists(arguments.initAttribs,arguments.tagName)) {
				returnValue = arguments.initAttribs[arguments.tagName];
			}
			return returnValue;
		</cfscript>
	</cffunction>

	<cffunction name="get_sharePath" access="public" output="false">
		<cfreturn variables.config.path>
	</cffunction>
	
	<cffunction name="get_shareClassPath" access="public" output="false">
		<cfreturn variables.config.classPath>
	</cffunction>
		
		
	<cffunction name="mergeAttributes" output="false" access="public" returntype="struct">
		<cfargument name="attributes">
		<cfargument name="rootStruct">
		<cfscript>
		var attributeStruct = arguments.attributes;
		var _attributes = arguments.attributes;
		var iStructKey = '';
		var root = arguments.rootStruct;
		/* for (iStructKey in _attributes) {
			if (structKeyExists(root,"_init")
				AND _attributes.id NEQ ''
				AND structKeyExists(root._init,_attributes.id)
				AND structKeyExists(root._init["#_attributes.id#"],iStructKey)) {
				attributeStruct["#iStructKey#"] = root._init["#_attributes.id#"]["#iStructKey#"];
			}
		} */
		if (structKeyExists(root,"_init") AND structKeyExists(root._init,_attributes.id)) {
			for (iStructKey IN root._init[attributes.id]) {
				try{
					_attributes[iStructKey] = root._init[attributes.id][iStructKey];
				} catch(any e){
					if(findNoCase(iStructKey,e.message) && findNoCase("undefined",e.message)){
						_attributes[iStructKey] = "";
					} else {
						// not sure what to do here
						_throw(
							message:e.message,
							detail:e.detail,
							errorcode:e.errorcode,
							type:e.type
						);
					}
				}
			}
		}
		return _attributes;
		</cfscript>
	</cffunction>
	
	<cffunction name="mixin" access="public">
		<cfargument name="mixinCode" required="true">
		<cfset structAppend(this,arguments.mixinCode)>
		<cfset structAppend(variables,arguments.mixinCode)>
		<cfset arguments.mixinCode.inject(this)>
	</cffunction>
	
	<cffunction name="_location" output="false" access="public">
		<cfargument name="url" required="true">
		<cfargument name="addtoken" default="false">
		<cfargument name="type" default="cf">
		<cfargument name="typeTarget" default="">
		
		<cfscript>
		var locationScript = "";
		var myContent = "";
		
		if(arguments.type EQ "cfajax"){
			if(NOT structKeyExists(arguments,"typeTarget"))
				_throw(
					message:"Missing type target argument",
					detail:"When using _location() with type of 'cfajax' it must have a declared argument for typeTarget. This tells which AJAX dom element ID to target the content towards."
				);
			_htmlHead('
				<script language="javascript" type="text/javascript">
				ColdFusion.navigate("#arguments.url#", "#arguments.typeTarget#");
				</script>
			');
			_abort();
		} else if(arguments.type EQ "js") {
			_htmlHead('
				<script language="javascript" type="text/javascript">
				document.location.href = "#arguments.url#";
				</script>
			');
			_abort();
		}
		</cfscript>
		<cflocation url="#arguments.url#" addtoken="#arguments.addtoken#">
		<cfabort> 
	</cffunction>
	
	<cffunction name="onRemoteStart" 
		description="I am called when " 
		displayname="onRemoteStart"
		 output="false" access="private" returntype="void">
		
		<cfscript>
		VARIABLES._API = REQUEST._API;
		VARIABLES.attributes = REQUEST.attributes;
		</cfscript>
		<cfsetting showdebugoutput="false">
	</cffunction>
	
	<cffunction name="onFirstCall" 
		description="I am called whenever the coop tag is first initiated" 
		displayname="onFirstCall"
		 output="false" access="public" returntype="struct">
		
		<cfargument name="init" default="#structNew()#">
		
		<cfset var _init = arguments.init>
		
		<cfreturn _init>
	</cffunction>
	
	<cffunction name="onPostBack" 
		description="I am called whenever a form postback happens." 
		displayname="onPostBack"
		 output="false" access="public" returntype="struct">
		
		<cfargument name="init" default="#structNew()#">
		
		<cfset var _init = arguments.init>
		
		<cfreturn _init>
	</cffunction>
	
	<cffunction name="beforeViewCall" 
		description="I am the last of the coop callbacks to get called." 
		displayname="onPostBack"
		 output="false" access="public" returntype="struct">
		
		<cfargument name="init" default="#structNew()#">
		
		<cfset var _init = arguments.init>
		
		<cfreturn _init>
	</cffunction>
	
	
	<cffunction name="onPageStart" output="false" access="public" returntype="struct">
		<cfargument name="init" default="#structNew()#">
		<cfset var _init = arguments.init>
		<cfreturn _init>
	</cffunction>
	
	<cffunction name="onPageEnd" output="false" access="public" returntype="void">
		
	</cffunction>
	
	<cffunction name="updatePageState" output="false" access="public">
		
	</cffunction>
	
	<cffunction name="initFields" access="public" output="false">
		<cfargument name="init">
		<cfargument name="fields">
		
		<cfscript>
		var _init = ARGUMENTS.init;
		var _fields = ARGUMENTS.fields;
		var curField = '';
		var i = 1;
		
		for(i=1; i<= listLen(_fields); i++) {
			curField = listGetAt(_fields,i);
			if (!structKeyExists(_init,curField)) {
				_init[curField] = '';
			}
		}
		</cfscript>
	</cffunction>
	
	<cffunction name="paramDomElement" access="public" output="false">
		<cfargument name="init" required="true">
		<cfargument name="field" required="true">
		<cfargument name="listFields" default="">
		<cfargument name="default" default="">
		<cfargument name="condition" default="true">
		
		<cfscript>
		var _init = ARGUMENTS.init;
		var myKey = "value";
		var tmp="";
		
		if(!structKeyExists(_init,ARGUMENTS.field)){
			_init[ARGUMENTS.field] = {};
		}
		if(listFindNoCase(ARGUMENTS.listFields,ARGUMENTS.field)){
			myKey = "selected";
		}
		if(!structKeyExists(_init[ARGUMENTS.field],myKey)){
			_init[ARGUMENTS.field][myKey] = "";
		}
		tmp = _init[ARGUMENTS.field][myKey];
		if(ARGUMENTS.condition && !len(tmp)){
			_init[ARGUMENTS.field][myKey] = ARGUMENTS.default;
		}
		</cfscript>
	</cffunction>
	
	<cffunction name="data2preDom" access="public" output="false">
        <cfargument name="init">
        <cfargument name="data">
        <cfargument name="fields">
        <cfargument name="listFields">
       
        <cfscript>
        var _init = ARGUMENTS.init;
        var i = 0;
        var field = "";
       
		if(isQuery(ARGUMENTS.data)){
			if(ARGUMENTS.data.recordCount){
				for(i=1;i<=listLen(ARGUMENTS.fields);i++){
					field = listGetAt(ARGUMENTS.fields,i);
					if(! structKeyExists(_init,field) OR !isStruct(_init[field]))
						_init[field] = structNew();
						_init[field].value = ARGUMENTS.data[field];
					}
					for(i=1;i<=listLen(ARGUMENTS.listFields);i++){
						field = listGetAt(ARGUMENTS.listFields,i);
						if(! structKeyExists(_init,field))
							_init[field] = structNew();
						_init[field].selected = ARGUMENTS.data[field];
					}
				}
			} else if(isStruct(ARGUMENTS.data)){
				for(i=1;i<=listLen(ARGUMENTS.fields);i++){
					field = listGetAt(ARGUMENTS.fields,i);
					if(! structKeyExists(_init,field))
						_init[field] = structNew();
					if(structKeyExists(ARGUMENTS.data,field))
						_init[field].value = ARGUMENTS.data[field];
				}
				for(i=1;i<=listLen(ARGUMENTS.listFields);i++){
					field = listGetAt(ARGUMENTS.listFields,i);
					if(! structKeyExists(_init,field))
						_init[field] = structNew();
					if(structKeyExists(ARGUMENTS.data,field))
						_init[field].selected = ARGUMENTS.data[field];
				}
		}
       
        return _init;
        </cfscript>
    </cffunction>
	
	<cffunction name="parse_mediaAlias" access="public" output="false">
		<cfargument name="api">
		<cfargument name="parseText">
		<cfscript>
		var alias = "";
		var aliasResult = ARGUMENTS.parseText;
		
		if(len(aliasResult) && refind("^@(.)*@",aliasResult)){
			alias = listFirst(aliasResult,"@");
			if(structKeyExists(ARGUMENTS.api,alias)){
				aliasResult = replace(aliasResult,"@#alias#@",ARGUMENTS.api[alias].get_mediaPath());
			}
		}
		
		return aliasResult;
		</cfscript>
	</cffunction>

	<!--- extended tags to functions --->
	<cffunction name="_createCookie">
		<cfargument name="name" required="true">
		<cfargument name="value" required="false" default="">
		<cfargument name="domain" required="false" default="">
		<cfargument name="expires" required="false" default="">
		<cfargument name="path" required="false" default="">
		<cfargument name="secure" required="false" default="">
		
		<cfset var cookieString = '#arguments.name#=#arguments.value#'>
		
		<cfif arguments.expires NEQ ''>
			<cfset cookieString = cookieString & ";expires=#arguments.expires#">
		</cfif>
		
		<cfif arguments.path NEQ ''>
			<cfset cookieString = cookieString & ";path=#arguments.path#">
		</cfif>
		
		<cfif arguments.domain NEQ ''>
			<cfset cookieString = cookieString & ";domain=#arguments.domain#">
		</cfif>
		
		<cfif arguments.secure NEQ ''>
			<cfset cookieString = cookieString & ";secure=#arguments.secure#">
		</cfif>
		<cfheader name="Set-Cookie"
				  value="#cookieString#">

	</cffunction>
	
	<cffunction name="_formatter">
		<cfargument name="format">
		<cfargument name="string">
		<cfargument name="args" required="false">
		<cfif structKeyExists(arguments,'args')>
			<cfparam name="arguments.args.formatterType" default="">
			<cfparam name="arguments.args.formatterMask" default="">
			<cfparam name="arguments.args.formatterVersion" default="">
		</cfif>
		<cfswitch expression="#arguments.format#">
			<cfcase value="date">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterMask)>
					<cfreturn dateFormat(arguments.string,arguments.args.formatterMask)>
				<cfelse>
					<cfreturn dateFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="decimal">
				<cfreturn decimalFormat(arguments.string)>
			</cfcase>
			<cfcase value="dollar">
				<cfreturn dollarFormat(arguments.string)>
			</cfcase>
			<cfcase value="htmlCode">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterVersion)>
					<cfreturn htmlCodeFormat(arguments.string,arguments.args.formatterVersion)>
				<cfelse>
					<cfreturn htmlCodeFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="htmlEdit">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterVersion)>
					<cfreturn htmlEditFormat(arguments.string,arguments.args.formatterVersion)>
				<cfelse>
					<cfreturn htmlEditFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="lsCurrency">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterType)>
					<cfreturn lsCurrencyFormat(arguments.string,arguments.args.formatterType)>
				<cfelse>
					<cfreturn lsCurrencyFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="lsDate">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterMask)>
					<cfreturn lsDateFormat(arguments.string,arguments.args.formatterMask)>
				<cfelse>
					<cfreturn lsDateFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="lsEuroCurrency">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterType)>
					<cfreturn lsEuroCurrencyFormat(arguments.string,arguments.args.formatterType)>
				<cfelse>
					<cfreturn lsEuroCurrencyFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="lsNumber">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterMask)>
					<cfreturn lsNumberFormat(arguments.string,arguments.args.formatterMask)>
				<cfelse>
					<cfreturn lsNumberFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="lsTime">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterMask)>
					<cfreturn lsTimeFormat(arguments.string,arguments.args.formatterMask)>
				<cfelse>
					<cfreturn lsTimeFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="number">
				<cfif structKeyExists(arguments,"args") AND len(arguments.args.formatterMask)>
					<cfreturn numberFormat(arguments.string,arguments.args.formatterMask)>
				<cfelse>
					<cfreturn numberFormat(arguments.string)>
				</cfif>
			</cfcase>
			<cfcase value="paragraph">
				<cfreturn paragraphFormat(arguments.string)>
			</cfcase>
			<cfdefaultCase>
				<cfthrow detail="Invalid formatter. The specified formatter is not currently supported.">
			</cfdefaultCase>
		</cfswitch>
	</cffunction>
	
	<cffunction name="_param" output="false" access="public">
		<cfargument name="structure" required="yes">
		<cfargument name="variable" required="yes">
		<cfargument name="value" required="no" default="">
		<cfscript>
		var item = "";
		var strItem = "";
		var items = listLen(ARGUMENTS.variable);
		var i={};
		var str = {};
		
		
		for(i.item = 1;i.item <= items;i.item++){
			str = ARGUMENTS.structure;
			for(i.str = 1;i.str < listLen(ARGUMENTS.variable,".");i.str++){
				strItem = listGetAt(ARGUMENTS.variable,i.str,".");
				if(! structKeyExists(str,strItem)){
					str[strItem] = {};
				}
				str = str[strItem];
			}
			item = listLast(listGetAt(ARGUMENTS.variable,i.item),".");
			if(!structKeyExists(ARGUMENTS.structure,item)){
				str[item] = arguments.value;
			}
		}
		
		return str[item];
		</cfscript>
	</cffunction>
    
   	<cffunction name="get_routeItem" output="true" access="public">
   		<cfargument name="position" default="1">
   		<cfargument name="default" default="">
   		<cfargument name="routeVar" default="#VARIABLES.attributes.__route#">
   		<cfscript>
   		if(isArray(ARGUMENTS.routeVar) && arrayLen(ARGUMENTS.routeVar)>=ARGUMENTS.position){
			return ARGUMENTS.routeVar[ARGUMENTS.position];
		} else {
			return ARGUMENTS.default;
		}
   		</cfscript>
	</cffunction>
    
   	<cffunction name="_dump" output="true" access="public">
		<cfargument name="var">
		<cfargument name="label" required="false" default="">
		<cfargument name="expand" default="true" required="false">
		<cfargument name="abort" default="false" required="false">
		<cfscript>
			if ( isSimpleValue(arguments.var)) {
				writeOutput("<br/> " & arguments.label & ": ");
			}
		</cfscript>
		<cfdump var="#arguments.var#" label="#arguments.label#" expand="#arguments.expand#">
		<cfif arguments.abort>
			<cfabort>
		</cfif>
	</cffunction>
	
	<cffunction name="_htmlHead" output="false" access="private">
		<cfargument name="text" required="true">
		
		<cfHtmlHead text="#arguments.text#">
	</cffunction>
    
   	<cffunction name="_rethrow" output="true" access="public">
	   <cftry>
	      <cfcatch>
	      <cfrethrow>
	      </cfcatch>
	   </cftry>
	   <cfthrow type="Context validation error" message="Context validation error for CFRETHROW.">
	</cffunction>
    
   	<cffunction name="_throw" output="true" access="public">
		<cfargument name="message" required="true">
		<cfargument name="detail" required="false" default="">
		<cfargument name="errorCode" required="false" default="">
		<cfargument name="extendedInfo" required="false" default="">
		<cfargument name="object" required="false" default="">
		<cfargument name="type" required="false" default="">
		<cfthrow message="#arguments.message#" detail="#arguments.detail#" errorcode="#arguments.errorCode#" extendedInfo="#arguments.extendedInfo#" type="#arguments.type#">
	</cffunction>
	
    <!--- extended coprocessor functions --->
	<cffunction name="setConfigVariables" access="private">
		<cfargument name="configXML">
	</cffunction>
	
</cfcomponent>